<!DOCTYPE html>
<html>

<head>
	<meta charset="utf-8">
	<title></title>
	<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>

<body>
	<div id="app">


	</div>
	<script type="text/javascript">
		function Vue(options) {
			this.$el = document.querySelector(options.el);
			this.$data = options.data();
			console.log(this)
			this._init(this, options.template, options.methods);
		}

		Vue.prototype._init = function (vm, template, methods) {
			var container = document.createElement('div');
			container.innerHTML = template;

			var showPool = new Map();
			var eventPool = new Map();

			initData(vm, showPool);
			initPool(container, methods, showPool, eventPool);
			bindEvent(vm, eventPool);
			render(vm, showPool, container);
		}


		function initData(vm, showPool) {
			var _data = vm.$data;
			for (var key in _data) {
				(function (key) {
					// 数据劫持
					Object.defineProperty(vm, key, {
						get: function () {
							return _data[key];
						},
						set: function (newValue) {
							_data[key] = newValue;
							update(vm, key, showPool);
						}
					})
				})(key)
			}
		};

		function initPool(container, methods, showPool, eventPool) {
			console.log(container.getElementsByName)
			// 拿到所有节点
			var _allNodes = container.getElementsByTagName('*');
			var dom = null;
			for (var i = 0; i < _allNodes.length; i++) {
				dom = _allNodes[i];

				var vIfData = dom.getAttribute('v-if');
				var vShowData = dom.getAttribute('v-show');
				var vEvent = dom.getAttribute('@click');
				// 保存dom及信息
				if (vIfData) {
					showPool.set(
						dom,
						{
							type: 'if',
							prop: vIfData
						},
					)
					dom.removeAttribute('v-if');
				} else if (vShowData) {
					showPool.set(
						dom,
						{
							type: 'show',
							prop: vShowData
						}
					)
					dom.removeAttribute('v-show');
				}
				if (vEvent) {
					eventPool.set(
						dom,
						methods[vEvent]
					);
					dom.removeAttribute('@click');
					console.log(dom)
				}
			}
		};

		function bindEvent(vm, eventPool) {
			// console.log(eventPool.has('dom'))
			console.log(eventPool)
			// for(var a of eventPool){
			// 	console.log(a.handler);
			// }
			for (var [dom, handler] of eventPool) {
				console.log(handler)
				console.log('事件')
				vm[handler.name] = handler;
				dom.addEventListener('click', vm[handler.name].bind(vm), false);
			}
		};

		function render(vm, showPool, container) {
			var _data = vm.$data;
			var _el = vm.$el;

			for (var [dom, info] of showPool) {
				console.log(info);
				console.log(_data[info.prop]);
				console.log('info')
				switch (info.type) {
					case 'if':
						info.comment = document.createComment(['v-if']);
						!_data[info.prop] && dom.parentNode.replaceChild(info.comment, dom);
						break;
					case 'show':
						!_data[info.prop] && (dom.style.display = 'none');
						break;
					default:
						break;
				}
			}
			_el.appendChild(container)
		};

		function update(vm, key, showPool) {
			var _data = vm.$data;

			for (var [dom, info] of showPool) {
				if (info.prop === key) {
					console.log(info);
					console.log('info')
					switch (info.type) {
						case 'if':
							console.log(dom.parentNode)
							!_data[key] ? dom.parentNode.replaceChild(info.comment, dom) :
								info.comment.parentNode.replaceChild(dom, info.comment);
							break;
						case 'show':
							!_data[key] ? (dom.style.display = 'none') :
								(dom.removeAttribute('style'))
							break;
						default:
							break;
					}
				}
			}
		}
		var vm = new Vue({
			el: '#app',
			data() {
				return {
					eventname: 'click',
					aatrr: 'href',
					linkIndex: 0,
					urls: [
						'https:www.taobao.com',
						'https:www.tmall.com',
						'https:www.jd.com',
					],
					isShowImg2: false,
					isShowImg1: false
				}

			},
			template: `
				<div>
					<div>
						<img v-if="isShowImg1" width='100' src='https://img1.baidu.com/it/u=21458005,3529547283&fm=26&fmt=auto'>
						<img v-show="isShowImg2" width='100' src='https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg-blog.csdnimg.cn%2Fimg_convert%2Fbb10737908ad706f2822d627887f5952.png&refer=http%3A%2F%2Fimg-blog.csdnimg.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1641948704&t=7596493c026d048362ae566da1fa68dc'>
					</div>
					<button @click="showImg1">显示图片1</button>
					<button @click="showImg2">显示图片2</button>
				</div>
				`,
			// `
			// 	<!--v-if是删除节点 使用注释节点做占位符 <!--v-if--> -->
			// 	<div id="">
			// 		<div id="">
			// 			<p v-if="linkIndex===0">
			// 				<a :href="urls[0]">淘宝</a>
			// 			</p>
			// 			<p v-else-if="linkIndex ==1">
			// 				<a :href="urls[1]">tmall</a>
			// 			</p>
			// 			<p v-else>
			// 				<a :href="urls[2]">京东</a>
			// 			</p>
			// 		</div>
			// 		<div id="">
			// 			<button type="button" @click="chengIndex(0)">淘宝</button>
			// 			<button type="button" @click="chengIndex(1)">天猫</button>
			// 			<button type="button" @click="chengIndex(2)">京东</button>
			// 		</div>
			// 	</div>

			// 	<!-- v-show是隐藏节点，display：none -->
			// 	<div id="">
			// 		<div id="">
			// 			<p v-show="linkIndex===0">
			// 				<a :href="urls[0]">淘宝</a>
			// 			</p>
			// 			<p v-show="linkIndex ==1">
			// 				<a :href="urls[1]">tmall</a>
			// 			</p>
			// 			<p v-show="linkIndex ==2">
			// 				<a :href="urls[2]">京东</a>
			// 			</p>
			// 		</div>
			// 		<div id="">
			// 			<button type="button" @click="chengIndex(0)">淘宝</button>
			// 			<button type="button" @click="chengIndex(1)">天猫</button>
			// 			<button type="button" @click="chengIndex(2)">京东</button>
			// 		</div>
			// 	</div>
			// `,
			methods: {
				// chengIndex() {
				// 	this.linkIndex = 1;
				// },
				showImg1() {
					this.isShowImg1 = !this.isShowImg1;
				},
				showImg2() {
					this.isShowImg2 = !this.isShowImg2;
				}
			}
		})
	</script>
</body>

</html>